<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc,fixuphtml" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>Java Remote Method Invocation: 8 - Stub/Skeleton Interfaces</title>
  <style type="text/css">
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <link rel="stylesheet" href="../../resources/jdk-default.css" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<main><h1 id="stubskeleton-interfaces">8 Stub/Skeleton Interfaces</h1>
<ul>
<li><a href="#the-remotestub-class">The <code>RemoteStub</code> Class</a></li>
<li><a href="#the-remotecall-interface">The <code>RemoteCall</code> Interface</a></li>
<li><a href="#the-remoteref-interface">The <code>RemoteRef</code> Interface</a></li>
<li><a href="#the-serverref-interface">The <code>ServerRef</code> Interface</a></li>
<li><a href="#the-skeleton-interface">The <code>Skeleton</code> Interface</a></li>
<li><a href="#the-operation-class">The <code>Operation</code> Class</a></li>
</ul>
<hr />
<p>This section contains the interfaces and classes used by the stubs and skeletons generated by the <code>rmic</code> stub compiler.</p>
<h2 id="the-remotestub-class">8.1 The <code>RemoteStub</code> Class</h2>
<p>The <code>java.rmi.server.RemoteStub</code> class is the common superclass for stubs of remote objects. Stub objects are surrogates that support exactly the same set of remote interfaces defined by the actual implementation of a remote object.</p>
<pre><code>package java.rmi.server;

public abstract class RemoteStub extends java.rmi.RemoteObject {
        protected RemoteStub() {...}
        protected RemoteStub(RemoteRef ref) {...}

        protected static void setRef(RemoteStub stub, RemoteRef ref) {...}
}</code></pre>
<p>The first constructor of <code>RemoteStub</code> creates a stub with a <code>null</code> remote reference. The second constructor creates a stub with the given remote reference, <em>ref</em>.</p>
<p>The <code>setRef</code> method is deprecated (and unsupported) as of the Java 2 SDK, Standard Edition, v1.2.</p>
<h3 id="type-equivalency-of-remote-objects-with-a-stub-class">8.1.1 Type Equivalency of Remote Objects with a Stub Class</h3>
<p>Clients interact with stub (surrogate) objects that have <em>exactly</em> the same set of remote interfaces defined by the remote object's class; the stub class does not include the non-remote portions of the class hierarchy that constitutes the object's type graph. This is because the stub class is generated from the most refined implementation class that implements one or more remote interfaces. For example, if C extends B and B extends A, but only B implements a remote interface, then a stub is generated from B, not C.</p>
<p>Because the stub implements the same set of remote interfaces as the remote object's class, the stub has the same type as the remote portions of the server object's type graph. A client, therefore, can make use of the built-in Java programming language operations to check a remote object's type and to cast from one remote interface to another.</p>
<p>Stubs are generated using the <code>rmic</code> compiler.</p>
<h3 id="the-semantics-of-object-methods-declared-final">8.1.2 The Semantics of Object Methods Declared <code>final</code></h3>
<p>The following methods are declared <code>final</code> in the <code>java.lang.Object</code> class and therefore cannot be overridden by any implementation:</p>
<ul>
<li><code>getClass</code></li>
<li><code>notify</code></li>
<li><code>notifyAll</code></li>
<li><code>wait</code></li>
</ul>
<p>The default implementation for <code>getClass</code> is appropriate for all objects written in the Java programming language, local or remote; so, the method needs no special implementation for remote objects. When used on a remote stub, the <code>getClass</code> method reports the exact type of the stub object, generated by <code>rmic</code>. Note that stub type reflects only the remote interfaces implemented by the remote object, not that object's local interfaces.</p>
<p>The <code>wait</code> and <code>notify</code> methods of <code>java.lang.Object</code> deal with waiting and notification in the context of the Java programming language's threading model. While use of these methods for remote stubs does not break the threading model, these methods do not have the same semantics as they do for local objects written in the Java programming language. Specifically, these methods operate on the client's local reference to the remote object (the stub), not the actual object at the remote site.</p>
<h2 id="the-remotecall-interface">8.2 The <code>RemoteCall</code> Interface</h2>
<p>The interface <code>RemoteCall</code> is an abstraction used by the stubs and skeletons of remote objects to carry out a call to a remote object.</p>
<p><strong>Note:</strong> The <code>RemoteCall</code> interface is deprecated as of the Java 2 SDK, Standard Edition, v1.2. The 1.2 stub protocol does not make use of this interface anymore. As of the Java 2 SDK, Standard Edition, v1.2, stubs now use the new <code>invoke</code> method which does not require <code>RemoteCall</code> as a parameter.</p>
<pre><code>package java.rmi.server;

import java.io.*;

public interface RemoteCall {
        ObjectOutput getOutputStream() throws IOException;
        void releaseOutputStream() throws IOException;
        ObjectInput getInputStream() throws IOException;
        void releaseInputStream() throws IOException;
        ObjectOutput getResultStream(boolean success)
                throws IOException, StreamCorruptedException;
        void executeCall() throws Exception;
        void done() throws IOException;
}</code></pre>
<p>The method <code>getOutputStream</code> returns the output stream into which either the stub marshals arguments or the skeleton marshals results.</p>
<p>The method <code>releaseOutputStream</code> releases the output stream; in some transports this will release the stream.</p>
<p>The method <code>getInputStream</code> returns the <code>InputStream</code> from which the stub unmarshals results or the skeleton unmarshals parameters.</p>
<p>The method <code>releaseInputStream</code> releases the input stream. This will allow some transports to release the input side of a connection early.</p>
<p>The method <code>getResultStream</code> returns an output stream (after writing out header information relating to the success of the call). Obtaining a result stream should only succeed once per remote call. If <em>success</em> is <code>true</code>, then the result to be marshaled is a normal return; otherwise the result is an exception. <code>StreamCorruptedException</code> is thrown if the result stream has already been obtained for this remote call.</p>
<p>The method <code>executeCall</code> does whatever it takes to execute the call.</p>
<p>The method <code>done</code> allows cleanup after the remote call has completed.</p>
<h2 id="the-remoteref-interface">8.3 The <code>RemoteRef</code> Interface</h2>
<p>The interface <code>RemoteRef</code> represents the handle for a remote object. Each stub contains an instance of <code>RemoteRef</code> that contains the concrete representation of a reference. This remote reference is used to carry out remote calls on the remote object for which it is a reference.</p>
<pre><code>package java.rmi.server;

public interface RemoteRef extends java.io.Externalizable {
        Object invoke(Remote obj,
                      java.lang.reflect.Method method,
                      Object[] params,
                      long opnum)
                throws Exception;

        RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum,
                           long hash) throws RemoteException;
        void invoke(RemoteCall call) throws Exception;
        void done(RemoteCall call) throws RemoteException;
        String getRefClass(java.io.ObjectOutput out);
        int remoteHashCode();
        boolean remoteEquals(RemoteRef obj);
        String remoteToString();
}</code></pre>
<p>The <code>invoke(Remote,Method,Object[],long)</code> method delegates method invocation to the stub's (<em>obj</em>) remote reference and allows the reference to take care of setting up the connection to the remote host, marshaling some representation for the <em>method</em> and parameters, <em>params</em>, then communicating the method invocation to the remote host. This method either returns the result of the method invocation on the remote object which resides on the remote host or throws a <code>RemoteException</code> if the call failed or an application-level exception if the remote invocation throws an exception. Note that the operation number, <em>opnum</em>, represents a hash of the method signature and may be used to encode the method for transmission.</p>
<p>The method hash to be used for the <em>opnum</em> parameter is a 64-bit (long) integer computed from the first two 32-bit values of the message digest of a particular byte stream using the National Institute of Standards and Technology (NIST) Secure Hash Algorithm (SHA-1). This byte stream contains a string as if it was written using the <code>java.io.DataOutput.writeUTF</code> method, consisting of the remote method's name followed by its method descriptor (see <em>The Java Virtual Machine Specification</em> (JVMS) for a description of method descriptors).</p>
<p>For example, if a method of a remote interface has the following name and signature:</p>
<pre><code>void myRemoteMethod(int count, Object obj, boolean flag)</code></pre>
<p>the string containing the remote method's name and descriptor would be the following:</p>
<pre><code>myRemoteMethod(ILjava/lang/Object;Z)V</code></pre>
<p>The 64-bit hash value is the little-endian composition of an eight byte sequence where the first four bytes are the first 32-bit value of the message digest in big-endian byte order and the last four bytes are the second 32-bit value of the message digest in big-endian byte order. For example, if the first two 32-bit values of the message digest are <code>0xB0B1B2B3</code> and <code>0xB4B5B6B7</code>, then the hash value would be <code>0xB7B6B5B4B3B2B1B0</code>.</p>
<p><strong>Note:</strong> The methods <code>newCall(RemoteObject,Operation[],int,long)</code>, <code>invoke(RemoteCall)</code>, and <code>done(RemoteCall)</code> are deprecated as of the Java 2 SDK, Standard Edition, v1.2. The stubs generated by <code>rmic</code> using the 1.2 stub protocol version do not use these methods any longer. The sequence of calls consisting of <code>newCall</code>, <code>invoke</code>, and <code>done</code> have been replaced by a new <code>invoke</code> method that takes a <code>Method</code> object as one of its parameters.</p>
<p>The method <code>newCall</code> creates an appropriate call object for a new remote method invocation on the remote object <em>obj</em>. The operation array, <em>op</em>, contains the available operations on the remote object. The operation number, <em>opnum</em>, is an index into the operation array which specifies the particular operation for this remote call. The interface <em>hash</em> is a 64-bit value used to enforce compatibility between a stub and skeleton using the v1.1 stub protocol. The interface hash is computed from the first two 32-bit values of the message digest of a particular byte stream using SHA-1. This byte stream contains data as if it was written using the <code>writeInt</code> and <code>writeUTF</code> methods of the interface <code>java.io.DataOutput</code>, consisting of the following items:</p>
<ul>
<li>(<code>int</code>) stub version number, always 1</li>
<li>for each remote method, in order of operation number:
<ul>
<li>(UTF-8) remote method name</li>
<li>(UTF-8) remote method descriptor (see The Java Virtual Machine Specification)</li>
</ul></li>
<li>for each declared exception, in lexicographic order of binary name:
<ul>
<li>(UTF-8) the name of the exception class</li>
</ul></li>
</ul>
<p>The interface hash value is composed from the message digest in the same manner as described above for the method hash used in the <code>invoke</code> method.</p>
<p>The method <code>invoke(RemoteCall)</code> executes the remote call. <code>invoke</code> will raise any &quot;user&quot; exceptions which should pass through and not be caught by the stub. If any exception is raised during the remote invocation, <code>invoke</code> should take care of cleaning up the connection before raising the &quot;user exception&quot; or <code>RemoteException</code>.</p>
<p>The method <code>done</code> allows the remote reference to clean up (or reuse) the connection. <code>done</code> should only be called if the <code>invoke</code> call returns successfully (non-exceptionally) to the stub.</p>
<p>The method <code>getRefClass</code> returns the nonpackage-qualified class name of the reference type to be serialized onto the stream <em>out</em>.</p>
<p>The method <code>remoteHashCode</code> returns a hashcode for a remote object. Two remote object stubs that refer to the same remote object will have the same hash code (in order to support remote objects as keys in hashtables). A <code>RemoteObject</code> forwards a call to its <code>hashCode</code> method to the <code>remoteHashCode</code> method of the remote reference.</p>
<p>The method <code>remoteEquals</code> compares two remote objects for equality. Two remote objects are equal if they refer to the same remote object. For example, two stubs are equal if they refer to the same remote object. A <code>RemoteObject</code> forwards a call to its <code>equals</code> method to the <code>remoteEquals</code> method of the remote reference.</p>
<p>The method <code>remoteToString</code> returns a <code>String</code> that represents the reference of this remote object.</p>
<h2 id="the-serverref-interface">8.4 The <code>ServerRef</code> Interface</h2>
<p>The interface <code>ServerRef</code> represents the server-side handle for a remote object implementation.</p>
<pre><code>package java.rmi.server;

public interface ServerRef extends RemoteRef {
        RemoteStub exportObject(java.rmi.Remote obj, Object data)
                throws java.rmi.RemoteException;
        String getClientHost() throws ServerNotActiveException;
}</code></pre>
<p>The method <code>exportObject</code> finds or creates a client stub object for the supplied <code>Remote</code> object implementation <em>obj</em>.The parameter <em>data</em> contains information necessary to export the object (such as port number).</p>
<p>The method <code>getClientHost</code> returns the host name of the current client. When called from a thread actively handling a remote method invocation, the host name of the client invoking the call is returned. If a remote method call is not currently being service, then <code>ServerNotActiveException</code> is called.</p>
<h2 id="the-skeleton-interface">8.5 The <code>Skeleton</code> Interface</h2>
<p>The interface <code>Skeleton</code> is used solely by the implementation of skeletons generated by the <code>rmic</code> compiler. A skeleton for a remote object is a server-side entity that dispatches calls to the actual remote object implementation.</p>
<p><strong>Note:</strong> The <code>Skeleton</code> interface was deprecated as of the Java 2 SDK, Standard Edition, v 1.2. Every 1.1 (and version 1.1 compatible skeletons generated in 1.2 using <code>rmic -vcompat</code>, the default) skeleton class generated by the <code>rmic</code> stub compiler implements this interface. Skeletons are no longer required for remote method call dispatch as of Java 2 SDK, Standard Edition, v1.2-compatible versions. To generate stubs that are compatible with 1.2 or later versions, use the command <code>rmic</code> with the option <code>-v1.2</code>.</p>
<pre><code>package java.rmi.server;

public interface Skeleton {
        void dispatch(Remote obj, RemoteCall call, int opnum, long hash)
                throws Exception;
        Operation[] getOperations();
}</code></pre>
<p>The <code>dispatch</code> method unmarshals any arguments from the input stream obtained from the <em>call</em> object, invokes the method (indicated by the operation number <em>opnum</em>) on the actual remote object implementation <em>obj</em>, and marshals the return value or throws an exception if one occurs during the invocation.</p>
<p>The <code>getOperations</code> method returns an array containing the operation descriptors for the remote object's methods.</p>
<h2 id="the-operation-class">8.6 The <code>Operation</code> Class</h2>
<p>The class <code>Operation</code> holds a description of a method in the Java programming language for a remote object.</p>
<p><strong>Note:</strong> The <code>Operation</code> interface is deprecated as of the Java 2 SDK, Standard Edition, v1.2. The 1.2 stub protocol no longer uses the old <code>RemoteRef.invoke</code> method which takes an <code>Operation</code> as one of its arguments. As of the Java 2 SDK, Standard Edition, v1.2, stubs now use the new <code>invoke</code> method which does not require <code>Operation</code> as a parameter.</p>
<pre><code>package java.rmi.server;

public class Operation {
        public Operation(String op) {...}
        public String getOperation() {...}
        public String toString() {...}
}</code></pre>
<p>An <code>Operation</code> object is typically constructed with the method signature.</p>
<p>The method <code>getOperation</code> returns the contents of the operation descriptor (the value with which it was initialized).</p>
<p>The method <code>toString</code> also returns the string representation of the operation descriptor (typically the method signature).</p>
</main><footer class="legal-footer"><hr/><a href="../../legal/copyright.html">Copyright</a> &copy; 1993, 2021, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.<br>All rights reserved. Use is subject to <a href="https://www.oracle.com/java/javase/terms/license/java17speclicense.html">license terms</a> and the <a href="https://www.oracle.com/technetwork/java/redist-137594.html">documentation redistribution policy</a>. <!-- Version 17.0.2+8-LTS-86 --></footer>
</body>
</html>